package com.market.web.controller;

import java.util.List;

import javax.faces.event.AbortProcessingException;
import javax.faces.event.ComponentSystemEvent;

import org.primefaces.model.StreamedContent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.market.domain.Picture;
import com.market.domain.Product;
import com.market.domain.Product.TYPE;
import com.market.domain.PurchaseSchedule;
import com.market.domain.Role;
import com.market.domain.User;
import com.market.manager.PictureManager;
import com.market.manager.ProductManager;
import com.market.util.CollectionUtil;
import com.market.web.controller.report.ReportController;
import com.market.web.model.MarketList;
import com.market.web.model.PictureModel;
import com.market.web.model.ProductModel;
import com.market.web.model.SupplierModel;

@Controller("productController")
@Scope("session")
public class ProductController extends
		GenericController<ProductManager, ProductModel, Product> {
	@Autowired
	private PictureModel pictureModel;
	@Autowired
	private SupplierModel supplierModel;
	@Autowired
	private ReportController reportController;

	@Override
	@Autowired
	protected void setModel(ProductModel model) {
		this.model = model;

	}

	@Override
	@Autowired
	protected void setManager(ProductManager manager) {
		this.manager = manager;
	}

	public void loadAllOrganicProducts() {
		this.model.setList(this.manager.fetchAllOrganicProducts());
		// load all related info of current product, so when switch to
		// information ,would not get "lazy loading" error.
		this.model.setCurrent(this.manager.fetchOne(this.model.getCurrent()
				.getId()));
	}

	public void emptyOrganicInventory() {
		for (Product product : this.getModel().getList()) {
			if (product.getIsOrganic() == Boolean.TRUE) {
				product.setInventory(0L);
				this.manager.store(product);
			}
		}
	}

	public void restoreOrganicInventory() {
		for (Product product : this.getModel().getList()) {
			if (product.getIsOrganic() == Boolean.TRUE) {
				product.setInventory(this.getModel().getOrganicInventory());
				this.manager.store(product);
			}
		}
	}

	public void loadAllTofuProducts() {
		this.model.setList(this.manager.fetchAllTofuProducts());
		// load all related info of current product, so when switch to
		// information ,would not get "lazy loading" error.
		this.model.setCurrent(this.manager.fetchOne(this.model.getCurrent()
				.getId()));
	}

	public void emptyTofuInventory() {
		for (Product product : this.getModel().getList()) {
			if (product.getType().equals(TYPE.TOFU)) {
				product.setInventory(0L);
				this.manager.store(product);
			}
		}
	}

	public void restoreTofuInventory() {
		for (Product product : this.getModel().getList()) {
			if (product.getType().equals(TYPE.TOFU)) {
				product.setInventory(this.getModel().getTofuInventory());
				this.manager.store(product);
			}
		}
	}

	public void loadWhoBuyItForCurrent() {
		this.getModelCurrent().setWhoBuyIts(
				reportController.loadWhoBuyIt(this.getModelCurrent()));
	}

	/**
	 * Return a pdf report for filtered product list
	 * 
	 * @return
	 */
	public StreamedContent getFilteredProductListPdf() {
		if (this.getModel().getFilteredList() != null
				&& this.getModel().getFilteredList().size() > 0) {
			return this.reportController.printProduct(this.getModel()
					.getFilteredList());
		} else
			return this.reportController
					.printProduct(this.getModel().getList());
	}

	public void initShopping() {
		List<Product> all = this.manager.fetchAllHaveInventory();
		this.model.setList(all);
	}

	public void initNotFreshHaveInventoryList() {
		this.model.setNotFreshHaveInventoryList(this.manager
				.fetchAllNotFreshHaveInventory());
	}

	public void initActiveWeeklyProducts() {
		List<Product> all = this.manager.fetchActiveWeeklyProducts();
		this.model.setList(all);
	}

	/**
	 * Add all selected pictures to current product And clear selected
	 * propertied after this operation finish
	 * 
	 */
	public void addSelectedPicsToCurrent() {
		Product current = this.getModelCurrent();
		List<Picture> selectedPics = pictureModel.getSelecteds();
		CollectionUtil<Picture> util = new CollectionUtil<Picture>();
		util.addAll(current.getPictures(), selectedPics);
		util.clearSelection(selectedPics); // Normally we have to clear selected
											// properties, after operation
											// finish
	}

	/**
	 * Remove all selected pictures from current product And clear selected
	 * propertied after this operation finish
	 * 
	 */
	public void removeSelectedPicsFromCurrent() {
		List<Picture> pictures = this.getModel().getCurrent().getPictures();
		CollectionUtil<Picture> util = new CollectionUtil<Picture>();
		List<Picture> unSelectedPictures = util.extractUnSelected(pictures);
		this.getModelCurrent().setPictures(unSelectedPictures);
		util.clearSelection(pictures); // Normally we have to clear selected
										// properties, after operation finish
	}

	/**
	 * Update current product's supplier, when user choose new supplier from
	 * chooseSupplierDialog.xhtml
	 */
	public void updateCurrentSupplier() {
		this.model.getCurrent().setSupplier(this.supplierModel.getCurrent());
	}

	/**
	 * This method extract selected purchase schedule and set to product's
	 * purchase schedule property Then save product to database;
	 */

	@Override
	public Product saveCurrent() {
		CollectionUtil<PurchaseSchedule> util = new CollectionUtil<PurchaseSchedule>();
		List<PurchaseSchedule> purchaseSchedules = util
				.extractSelected(this.model.getAllPurchaseSchedules());
		this.getModel().getCurrent().setPurchaseSchedules(purchaseSchedules);
		return super.saveCurrent();
	}

	public void saveCurrentPriceInfo() {
		this.manager.storePriceInfo(this.model.getCurrent());
	}

	public void saveCurrentInventory() {
		this.manager.storeInventory(getModelCurrent());
	}

}
